package com.lry.jvm.rtda.heap;


import com.lry.jvm.classfile.constantpool.ConstantMemberRefInfo;
import com.lry.jvm.util.Util;

public class FieldRef extends MemberRef {

    private JField jField;

    public FieldRef(RuntimeConstantPool rcp,ConstantMemberRefInfo memberRefInfo) {
        super(memberRefInfo);
        this.setRcp(rcp);
    }

    public JField resolvedField(){
        if(null==jField){
            resolveFieldRef();
        }
        return jField;
    }

    private void resolveFieldRef() {
        JClass d = getRcp().getJClass();
        JClass c = resolvedClass();

        jField = lookupField(c,getName(),getDescriptor());
        if(null==jField){
            Util.panic("java.lang.NoSuchFieldError");
        }

        if (!jField.isAccessibleTo(d)) {
            Util.panic("java.lang.IllegalAccessError");
        }
    }

    private JField lookupField(JClass c, String name, String descriptor) {
        for(JField field : c.getFields()){
            if(field.getName().equals(name)&&field.getDescriptor().equals(descriptor)){
                return field;
            }
        }

        for(JClass jClass :c.getInterfaces()){
            JField f = lookupField(jClass,name,descriptor);
            if(null!=f){
                return f;
            }
        }

        if(c.getSuperClass()!=null){
            return lookupField(c.getSuperClass(),name,descriptor);
        }
        return null;
    }
}
